home *** CD-ROM | disk | FTP | other *** search
/ Shareware Super Platinum 8 / Shareware Super Platinum 8.iso / mac / WIN_PRO / DS-1.ZIP;1 / PREPROC.ZIP / PMEM.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-02-15  |  9.2 KB  |  428 lines

  1. /*
  2.  * This file does most of the memory management. For fixed length blocks,
  3.  *  it maintains free lists. When a list is empty, it mallocs a new block.
  4.  */
  5.  
  6. #include "../preproc/preproc.h"
  7.  
  8. struct src *src_stack = NULL;  /* stack of token sources */
  9.  
  10. /*
  11.  * Free lists.
  12.  */
  13. static struct macro      *macro_free     = NULL;
  14. static struct token      *token_free     = NULL;
  15. static struct tok_lst    *tok_lst_free   = NULL;
  16. static struct id_lst     *id_lst_free    = NULL;
  17. static struct src        *src_free       = NULL;
  18. static struct char_src   *char_src_free  = NULL;
  19. static struct mac_expand *mac_expand_free = NULL;
  20. static struct paste_lsts *paste_lsts_free = NULL;
  21. static struct str_buf    *str_buf_free    = NULL;
  22.  
  23. #include "../preproc/pproto.h"
  24.  
  25. /*
  26.  * new_macro - allocate a new entry for the macro symbol table.
  27.  */
  28. struct macro *new_macro(mname, category, multi_line, prmlst, body)
  29. char *mname;
  30. int category;
  31. int multi_line;
  32. struct id_lst *prmlst;
  33. struct tok_lst *body;
  34.    {
  35.    struct macro *mp;
  36.  
  37.    if ((mp = macro_free) == NULL)
  38.       mp = NewStruct(macro);
  39.    else
  40.       macro_free = macro_free->next;
  41.    mp->mname = mname;
  42.    mp->category = category;
  43.    mp->multi_line = multi_line;
  44.    mp->prmlst = prmlst;
  45.    mp->body = body;
  46.    mp->ref_cnt = 1;
  47.    mp->recurse = 0;
  48.    mp->next = NULL;
  49.    return mp;
  50.    }
  51.  
  52. /*
  53.  * new_token - allocate a new token.
  54.  */
  55. struct token *new_token(id, image, fname, line)
  56. int id;
  57. char *image;
  58. char *fname;
  59. int line;
  60.    {
  61.    struct token *t;
  62. #if IntBits == 16
  63.    static firsttime=1;
  64.  
  65.    /*
  66.     *  Get 64K worth of tokens in one alloc() to reduce memory overhead.
  67.     */
  68.    if (firsttime) {
  69.       unsigned int num = 64000 / sizeof(struct token);
  70.       int i;
  71.       firsttime = 0;
  72.       token_free = (struct token *)alloc(num * sizeof(struct token));
  73.       for(i = 0; i < num-1; i++)
  74.          token_free[i].next = &(token_free[i+1]);
  75.       token_free[num].next = NULL;
  76.       }
  77. #endif                    /* IntBits == 16 */
  78.  
  79.    if ((t = token_free) == NULL)
  80.       t = NewStruct(token);
  81.    else
  82.       token_free = token_free->next;
  83.    t->tok_id = id;
  84.    t->image = image;
  85.    t->fname = fname;
  86.    t->line = line;
  87.    t->flag = 0;
  88.    return t;
  89.    }
  90.  
  91. /*
  92.  * copy_t - make a copy of a token.
  93.  */
  94. struct token *copy_t(t)
  95. struct token *t;
  96.    {
  97.    struct token *t1;
  98.  
  99.    if (t == NULL)
  100.       return NULL;
  101.  
  102.    if ((t1 = token_free) == NULL)
  103.       t1 = NewStruct(token);
  104.    else
  105.       token_free = token_free->next;
  106.    *t1 = *t;
  107.    return t1;
  108.    }
  109.  
  110. /*
  111.  * new_t_lst - allocate a new element for a token list.
  112.  */
  113. struct tok_lst *new_t_lst(tok)
  114. struct token *tok;
  115.    {
  116.    struct tok_lst *tlst;
  117.  
  118.    if ((tlst = tok_lst_free) == NULL)
  119.       tlst = NewStruct(tok_lst);
  120.    else
  121.       tok_lst_free = tok_lst_free->next;
  122.    tlst->t = tok;
  123.    tlst->next = NULL;
  124.    return tlst;
  125.    }
  126.  
  127. /*
  128.  * new_id_lst - allocate a new element for an identifier list.
  129.  */
  130. struct id_lst *new_id_lst(id)
  131. char *id;
  132.    {
  133.    struct id_lst *ilst;
  134.  
  135.    if ((ilst = id_lst_free) == NULL)
  136.       ilst = NewStruct(id_lst);
  137.    else
  138.       id_lst_free = id_lst_free->next;
  139.  
  140.    ilst->id = id;
  141.    ilst->next = NULL;
  142.    return ilst;
  143.    }
  144.  
  145. /*
  146.  * new_cs - allocate a new structure for a source of tokens created from
  147.  *  characters.
  148.  */
  149. struct char_src *new_cs(fname, f, bufsize)
  150. char *fname;
  151. FILE *f;
  152. int bufsize;
  153.    {
  154.    struct char_src *cs;
  155.  
  156.    if ((cs = char_src_free) == NULL) {
  157.       cs = NewStruct(char_src);
  158.       cs->bufsize = 0;
  159.       }
  160.    else
  161.       char_src_free = char_src_free->next;
  162.  
  163.    /*
  164.     * Insure the character and line number buffers are large enough.
  165.     */
  166.    if (cs->bufsize < bufsize) {
  167.       if (cs->bufsize > 0) {
  168.          free((char *)cs->char_buf);
  169.          free((char *)cs->line_buf);
  170.          }
  171.       cs->char_buf = (int *)alloc((unsigned int)(sizeof(int) * bufsize));
  172.       cs->line_buf = (int *)alloc((unsigned int)(sizeof(int) * bufsize));
  173.       cs->bufsize = bufsize;
  174.       }
  175.  
  176.    cs->fname = fname;
  177.    cs->f = f;
  178.    cs->line_adj = 0;
  179.    cs->tok_sav = NULL;
  180.    cs->dir_state = CanStart;
  181.  
  182.    return cs;
  183.    }
  184.  
  185. /*
  186.  * new_me - allocate a new structure for a source of tokens dirived
  187.  *  from macro expansion.
  188.  */
  189. struct mac_expand *new_me(m, args, exp_args)
  190. struct macro *m;
  191. struct tok_lst **args;
  192. struct tok_lst **exp_args;
  193.    {
  194.    struct mac_expand *me;
  195.  
  196.    if ((me = mac_expand_free) == NULL)
  197.       me = NewStruct(mac_expand);
  198.    else
  199.       mac_expand_free = mac_expand_free->next;
  200.  
  201.    me->m = m;
  202.    me->args = args;
  203.    me->exp_args = exp_args;
  204.    me->rest_bdy = m->body;
  205.    return me;
  206.    }
  207.  
  208. /*
  209.  * new_plsts - allocate a element for a list of token lists used as
  210.  *  as source of tokens dirived from a sequence of token pasting
  211.  *  operations.
  212.  */
  213. struct paste_lsts *new_plsts(trigger, tlst, plst)
  214. struct token *trigger;
  215. struct tok_lst *tlst;
  216. struct paste_lsts *plst;
  217.    {
  218.    struct paste_lsts *plsts;
  219.  
  220.    if ((plsts = paste_lsts_free) == NULL)
  221.       plsts = NewStruct(paste_lsts);
  222.    else
  223.       paste_lsts_free = paste_lsts_free->next;
  224.  
  225.    plsts->trigger = trigger;
  226.    plsts->tlst = tlst;
  227.    plsts->next = plst;
  228.    return plsts;
  229.    }
  230.  
  231. /*
  232.  * get_sbuf - dynamically allocate a string buffer.
  233.  */
  234. struct str_buf *get_sbuf()
  235.    {
  236.    struct str_buf *sbuf;
  237.  
  238.    if ((sbuf = str_buf_free) == NULL) {
  239.       sbuf = NewStruct(str_buf);
  240.       init_sbuf(sbuf);
  241.       }
  242.    else
  243.       str_buf_free = str_buf_free->next;
  244.  
  245.    return sbuf;
  246.    }
  247.  
  248. /*
  249.  * push_src - push an entry on the stack of tokens sources. This entry
  250.  *  becomes the current source.
  251.  */
  252. novalue push_src(flag, ref)
  253. int flag;
  254. union src_ref *ref;
  255.    {
  256.    struct src *sp;
  257.  
  258.    if ((sp = src_free) == NULL) 
  259.       sp = NewStruct(src);
  260.    else
  261.       src_free = src_free->next;
  262.  
  263.    sp->flag = flag;
  264.    sp->cond = NULL;
  265.    sp->u = *ref;
  266.    sp->ntoks = 0;
  267.  
  268.    if (src_stack->flag == CharSrc)
  269.       src_stack->u.cs->next_char = next_char;
  270.    sp->next = src_stack;
  271.    src_stack = sp;
  272.    }
  273.    
  274. /*
  275.  * free_t - free a token.
  276.  */
  277. novalue free_t(t)
  278. struct token *t;
  279.    {
  280.    if (t != NULL) {
  281.       t->next = token_free;
  282.       token_free = t;
  283.       }
  284.    }
  285.  
  286. /*
  287.  * free_t_lst - free a token list.
  288.  */
  289. novalue free_t_lst(tlst)
  290. struct tok_lst *tlst;
  291.    {
  292.    if (tlst == NULL)
  293.       return;
  294.    free_t(tlst->t);
  295.    free_t_lst(tlst->next);
  296.    tlst->next = tok_lst_free;
  297.    tok_lst_free = tlst;
  298.    }
  299.    
  300. /*
  301.  * free_id_lst - free an identifier list.
  302.  */
  303. novalue free_id_lst(ilst)
  304. struct id_lst *ilst;
  305.    {
  306.    if (ilst == NULL)
  307.        return;
  308.    free_id_lst(ilst->next);
  309.    ilst->next = id_lst_free;
  310.    id_lst_free = ilst;
  311.    }
  312.    
  313. /*
  314.  * free_m - if there are no more pointers to this macro entry, free it
  315.  *  and other associated storage.
  316.  */
  317. novalue free_m(m)
  318. struct macro *m;
  319.    {
  320.    if (--m->ref_cnt != 0)
  321.       return;
  322.    free_id_lst(m->prmlst);
  323.    free_t_lst(m->body);
  324.    m->next = macro_free;
  325.    macro_free = m;
  326.    }
  327.  
  328. /*
  329.  * free_m_lst - free a hash chain of macro symbol table entries.
  330.  */
  331. novalue free_m_lst(m)
  332. struct macro *m;
  333.    {
  334.    if (m == NULL)
  335.       return;
  336.    free_m_lst(m->next);
  337.    free_m(m);
  338.    }
  339.  
  340. /*
  341.  * free_plsts - free an entry from a list of token lists used in
  342.  *  token pasting.
  343.  */
  344. novalue free_plsts(plsts)
  345. struct paste_lsts *plsts;
  346.    {
  347.    plsts->next = paste_lsts_free;
  348.    paste_lsts_free = plsts;
  349.    }
  350.  
  351. /*
  352.  * rel_sbuf - free a string buffer.
  353.  */
  354. novalue rel_sbuf(sbuf)
  355. struct str_buf *sbuf;
  356.    {
  357.    sbuf->next = str_buf_free;
  358.    str_buf_free = sbuf;
  359.    }
  360.  
  361. /*
  362.  * pop_src - pop the top entry from the stack of tokens sources.
  363.  */
  364. novalue pop_src()
  365.    {
  366.    struct src *sp;
  367.    struct char_src *cs;
  368.    struct mac_expand *me;
  369.    int i;
  370.  
  371.    if (src_stack->flag == DummySrc)
  372.       return; /* bottom of stack */
  373.  
  374.    sp = src_stack;
  375.    src_stack = sp->next; /* pop */
  376.  
  377.    /*
  378.     * If the new current source is a character source, reload global
  379.     *  variables used in tokenizing the characters.
  380.     */
  381.    if (src_stack->flag == CharSrc) {
  382.       first_char = src_stack->u.cs->char_buf;
  383.       next_char = src_stack->u.cs->next_char;
  384.       last_char = src_stack->u.cs->last_char;
  385.       }
  386.  
  387.    /*
  388.     * Make sure there is no unclosed conditional compilation in the
  389.     *  source we are poping.
  390.     */
  391.    if (sp->cond != NULL)
  392.       errt2(sp->cond->t, "no matching #endif for #", sp->cond->t->image);
  393.  
  394.    /*
  395.     * Free any storage that the stack entry still references.
  396.     */
  397.    switch (sp->flag) {
  398.       case CharSrc:
  399.          cs = sp->u.cs;
  400.          if (cs->f != NULL)
  401.             fclose(cs->f);
  402.          cs->next = char_src_free;
  403.          char_src_free = cs;
  404.          break;
  405.       case MacExpand:
  406.          me = sp->u.me;
  407.          if (me->args != NULL) {
  408.             for (i = 0; i < me->m->category; i++) {
  409.                free_t_lst(me->args[i]);
  410.                free_t_lst(me->exp_args[i]);
  411.                }
  412.             free((char *)me->args);
  413.             free((char *)me->exp_args);
  414.             }
  415.          --me->m->recurse;
  416.          free_m(me->m);
  417.          me->next = mac_expand_free;
  418.          mac_expand_free = me;
  419.          break;
  420.       }
  421.  
  422.    /*
  423.     * Free the stack entry.
  424.     */
  425.    sp->next = src_free;
  426.    src_free = sp;
  427.    }
  428.